/**
  * @file imagenpgm.cpp
  * @brief Fichero que incluye las definiciones de las funciones miembro de la clase ImagenPGM.
  *
  */

  /* Copyright 2010 Antonio Ruano Cuesta
 *
 * This program is free software: you can redistribute it and/or modify it under 
 * the terms of the GNU General Public License as published by the Free Software 
 * Foundation, either version 3 of the License, or (at your option) any later 
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with 
 * this program. If not, see <http://www.gnu.org/licenses/>
*/
  
#include <new>
#include <iostream>
#include <fstream>
#include "imagenpgm.h"

using namespace std;

ImagenPGM::ImagenPGM()
{
	filas=0;
	cols=0;
	img=0;
}

ImagenPGM::ImagenPGM(int fils, int colum)
{
	if(fils > 0 && colum > 0){

		filas=fils;
		cols=colum;

		img = new (nothrow) byte *[fils];

		for(int i = 0 ; i < fils ; i++)
			img[i] = new (nothrow) byte [colum];
	}
	else{
		img=0;
	}	
}

ImagenPGM::ImagenPGM(const ImagenPGM &im)
{
	filas=im.filas;
	cols=im.cols;

	if (filas > 0 && cols > 0){
		
		img = new (nothrow) byte * [filas];
		for(int i = 0 ; i < filas ; ++i)
			img[i] = new (nothrow) byte [cols];

		for(int i = 0 ; i < filas ; ++i)
			for(int j = 0 ; j < cols ; ++j)
				img[i][j] = im.img[i][j];
	}
	else
		img=0;
}

ImagenPGM::~ImagenPGM()
{
	for(int i = 0 ; i < filas ; ++i)
		delete [] img[i];

	delete [] img;
}

ImagenPGM& ImagenPGM::operator= (const ImagenPGM &im)
{
	
	if(this != &im){
	
		if (filas > 0 && cols > 0){
		
			for(int i = 0 ; i < filas ; ++i)
			delete [] img[i];

			delete [] img;
		}

		filas=im.filas;
		cols=im.cols;

		img = new (nothrow) byte *[filas];

		for(int i = 0 ; i < filas ; ++i)
			img[i] = new (nothrow) byte [cols];

		for(int i = 0 ; i < filas ; ++i)
			for(int j = 0 ; j < cols ; ++j)
				img[i][j] = im.img[i][j];
	}

	return *this;
}

int ImagenPGM::num_filasPGM() const
{
	return filas;
}

int ImagenPGM::num_columnasPGM() const
{
	return cols;
}

void ImagenPGM::set_pixPGM(int fila, int col, byte valor)
{
	img[fila][col] = valor;
}

byte ImagenPGM::get_pixPGM(int fila, int col) const
{
	return img[fila][col];
}

void ImagenPGM::InsertaImagenPGM(const char *nombre)
{
	ifstream fi;
	const int TAM_LINE = 70;
	char buffer[TAM_LINE];
	int aux;
	
	fi.open (nombre);

	if (!fi){
		cerr<<"Error en la apertura del fichero."<<endl;
		exit(1);
	}

	fi.getline(buffer,TAM_LINE);
	
	if (strcmp("P5", buffer)){
		cerr<<"La imagen proporcionada no es PPM."<<endl;
		exit(1);
	}

	fi.getline(buffer,TAM_LINE,' ');

	while (!strcmp("#", buffer)){
		
		fi.ignore (TAM_LINE,'\n');
		fi.getline(buffer,TAM_LINE, ' ');
	}

	aux = atol(buffer);

	filas = aux;

	fi>>aux;

	cols = aux;

	const int TAM_BUF = filas * cols;
	unsigned char p [TAM_BUF];
	int contador = 0;

	img = new (nothrow) byte *[filas];

	for(int i = 0 ; i < filas ; ++i)
		img[i] = new (nothrow) byte [cols];

	fi.read((char *)p,TAM_BUF);
	
	for (int i = 0 ; i < filas ; i++)
		for (int j = 0 ; j < cols ; j++){

			img[i][j] = p[contador];
			contador++;
			
		}
	
	fi.close();

}

bool ImagenPGM::EscribeImagenPGM(const char *nombre)
{
	const int TAM_BUFFER = filas*cols;
	byte p[TAM_BUFFER];
	int contador = 0;
	
	ofstream fo;

	fo.open (nombre);

	if (!fo){
		cout<<"Error al crear el fichero, no se ha podido guardar la imagen"<<endl;
		return false;
	}

	fo<<"P5"<<endl;
	fo<<"# Imagen creada por Antonio Ruano Cuesta"<<endl;
	fo<<filas<<" "<<cols<<endl;
	fo<<255<<endl;

	for(int i = 0 ; i < filas ; ++i){
		
		for(int j = 0 ; j < cols ; ++j){

			p[contador] = img[i][j];
			contador++;
			
		}
	}

	fo.write((const char *)p,filas*cols);	

	fo.close();
	return true;
}
